﻿using AnimatedGif;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Imgs2Gif
{
    public partial class MainForm : Form
    {
        private class ListViewIndexComparer : System.Collections.IComparer
        {
           public int Compare(object x, object y)
            {
                return ((ListViewItem)x).Index - ((ListViewItem)y).Index;
            }
        }
        ImageList imageList1;
        public MainForm()
        {
            InitializeComponent();
            listView1.ListViewItemSorter = new ListViewIndexComparer();
            imageList1 = new ImageList();
            imageList1.ImageSize = new Size(200, 200);//大图标显示的尺寸
            
            this.listView1.View = View.LargeIcon;
            this.listView1.LargeImageList = imageList1;
        }

        bool isPic(string pic)
        {
            return pic.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || pic.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase);
        }

        private void bt_select_folder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.Description = "请选择文件夹:";
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                var imageFilePaths = System.IO.Directory.GetFiles(fbd.SelectedPath).Where(s => isPic(s));
                 
                foreach (var img in imageFilePaths)
                {
                    FileInfo fileInfo = new FileInfo(img);
                    imageList1.Images.Add(fileInfo.FullName, GetPicBySize(Image.FromFile(img), imageList1.ImageSize));

                    ListViewItem li = new ListViewItem();
                    li.Tag = fileInfo.FullName;
                    li.Text = fileInfo.Name;
                    li.ImageKey = fileInfo.FullName;         //对应指定即可
                    listView1.Items.Add(li);
                }
            }
        }

        public static Image GetPicBySize(Image image, Size size)
        {
            int width = size.Width;
            int height = size.Height;
            float picWidth = image.Width;
            float picHeight = image.Height;
            float t1 = width / picWidth;
            float t2 = height / picHeight;
            float t = t1 > t2 ? t2 : t1;
            int npicWidth = (int)(picWidth * t);
            int npicHeight = (int)(picHeight * t);

            int x = width > npicWidth ? (width - npicWidth) / 2 : 0;
            int y = height > npicHeight ? (height - npicHeight) / 2 : 0;

            Bitmap thumb = new Bitmap(width, height);
            using (Graphics g_thumb = Graphics.FromImage(thumb))
            {
                g_thumb.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g_thumb.DrawImage(image,x, y, npicWidth, npicHeight);
            }
            return thumb;
        }

        private void bt_create_gif_Click(object sender, EventArgs e)
        {
            if (listView1.Items.Count == 0) return;

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = ".gif";
            sfd.Filter = "*.gif|gif 文件";   // 设置文件类型为文本文件
            sfd.FileName = "gif.gif";   // 文件默认名
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                CreateGif(sfd.FileName);
            }
        }


        public void CreateGif(string gifPath)
        {
            Size size = new Size((int)num_width.Value, (int)num_height.Value);
            // 33ms delay (~30fps)
            int delay = (int)num_delay.Value;
            using (var gif = AnimatedGif.AnimatedGif.Create(gifPath, delay))
            {
                foreach(ListViewItem li in listView1.Items)
                {
                    string img = (string)li.Tag;
                    if (cb_auto_size.Checked)
                    {
                        gif.AddFrame(img, delay: -1, quality: GifQuality.Bit8);
                    }
                    else
                    {
                        gif.AddFrame(GetPicBySize(Image.FromFile(img), size), delay: -1, quality: GifQuality.Bit8);
                    }
                }
            }
            this.pic_gif.ImageLocation = gifPath;
        }


        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            int targetIndex = listView1.InsertionMark.Index;
            if (targetIndex == -1)
            {
                //return;
            }
            if (listView1.InsertionMark.AppearsAfterItem)
            {
                targetIndex++;
            }

            string[] path = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            if (path!=null && path.Length > 0)
            {
                if (targetIndex == -1) targetIndex = 0;
                foreach (string s in path)
                {
                    if (isPic(s))
                    {
                        FileInfo fileInfo = new FileInfo(s);
                        imageList1.Images.Add(fileInfo.FullName, GetPicBySize(Image.FromFile(s), imageList1.ImageSize));

                        ListViewItem li = new ListViewItem();
                        li.Tag = fileInfo.FullName;
                        li.Text = fileInfo.Name;
                        li.ImageKey = fileInfo.FullName;
                        listView1.Items.Insert(targetIndex, li);
                        targetIndex++;
                    }
                }
            }
            else
            {
                ListViewItem draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
                //Point ptScreen = new Point(e.X, e.Y);
                //Point pt = listView1.PointToClient(ptScreen);
                //ListViewItem targetItem = listView1.GetItemAt(pt.X, pt.Y);//拖动的项将放置于该项之前
            
                //if (null == targetItem || targetItem == draggedItem)
                //    return;

                // NeedForFix: 项实际已经交换，但是显示没有交换
                listView1.BeginUpdate();
          
                listView1.Items.Insert(targetIndex, (ListViewItem)draggedItem.Clone());
                listView1.Items.Remove(draggedItem);

            }

            listView1.EndUpdate();
        }

        //拖拽进入ListView，判断拖拽的数据格式，并设置拖拽的效果。
        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.AllowedEffect;
            
            string[] path = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            if (path != null)
            {
                foreach (string s in path)
                {
                    if (isPic(s))
                    {
                        e.Effect = e.AllowedEffect;
                        return;
                    }
                }
                e.Effect = DragDropEffects.None;
            }
        }

        private void listView1_DragLeave(object sender, EventArgs e)
        {
            listView1.InsertionMark.Index = -1;
        }

        private void listView1_DragOver(object sender, DragEventArgs e)
        {
            Point ptScreen = new Point(e.X, e.Y);
            Point pt = listView1.PointToClient(ptScreen);
            ListViewItem item = listView1.GetItemAt(pt.X, pt.Y);
          
            int targetIndex = listView1.InsertionMark.NearestIndex(pt);
            if (targetIndex >-1)
            {
                Rectangle itemBounds = listView1.GetItemRect(targetIndex);
                if (pt.X > itemBounds.Left + (itemBounds.Width / 2))
                {
                    listView1.InsertionMark.AppearsAfterItem = true;
                }
                else {
                    listView1.InsertionMark.AppearsAfterItem = false;
                }
            }
            listView1.InsertionMark.Index = targetIndex;
            //if (item != null)
            //    item.Checked = true;
        }

        private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            listView1.DoDragDrop(e.Item, DragDropEffects.Move);
        }
    }
}

